<template>
  <el-card
    shadow="always"
    style="margin: 2px 5px"
    :body-style="{
      padding: '20px',
      height: 'calc(100vh - 100px)',
      'overflow-y': 'auto',
    }"
  >
    <div class="project-wrapper">
      <ProjectCard
        v-for="project in projectStore.projectList"
        :key="project.id"
        :project="project"
        @click="selectProject(project)"
        :class="{
          'selected-project': project.id === projectStore.selectedProject.id,
        }"
      ></ProjectCard>
    </div>

    <el-row>
      <el-col :span="12">
        <el-button
          type="primary"
          size="default"
          @click="runProject"
          :icon="VideoPlay"
          >运行项目</el-button
        >
        <el-button
          type="primary"
          size="default"
          @click="downloadClient"
          :icon="Download"
          >下载客户端</el-button
        >
        <el-button
          type="primary"
          size="default"
          @click="runOnClient"
          :icon="VideoPlay"
          :disabled="!selectedClients.length"
          >在客户端运行</el-button
        >
        <el-select
          style="margin: 0 10px"
          v-model="selectedClients"
          multiple
          value-key=""
          placeholder="请选择要执行的客户端"
          clearable
          filterable
        >
          <el-option
            v-for="client in clientList"
            :key="client"
            :value="client"
            :label="client"
          >
          </el-option>
        </el-select>
        <el-button
          type="success"
          size="default"
          @click="listClients"
          :icon="Refresh"
          >刷新客户端列表</el-button
        >
      </el-col>
    </el-row>

    <el-card
      style="margin-top: 10px"
      shadow="always"
      :body-style="{ padding: '10px' }"
    >
      <template #header>
        <div>
          <span class="card-title">日志展示</span>
        </div>
      </template>
      <el-tabs v-model="selectedLogger" type="card" tab-position="top">
        <el-tab-pane
          v-for="logger in loggerList"
          :key="logger.runner"
          :label="logger.runner"
          :name="logger.runner"
        >
          <div class="log-wrapper">
            <el-scrollbar>
              <p v-for="log in logger.content" :key="log.timestamp">
                <span class="WARN">{{ log.timestamp }}</span>
                <span class="INFO"> [{{ log.threadName }}] </span>
                <span>{{ log.loggerName }} - </span>
                <span :class="log.level">{{ log.level }} :</span>
                <span>{{ log.message }}</span>
              </p>
            </el-scrollbar>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-card>
  </el-card>
</template>

<script setup lang="ts">
import { useProjectStore } from "@/stores/sunnyProjectStore";
import ProjectCard from "./project/ProjectCard.vue";
import { onMounted, onUnmounted } from "vue";
import type { SunnyProject } from "@/types/sunnyProject/type";
import { distributeRunApi, runProjectApi } from "@/api/sunnyrun";
import { ElMessage } from "element-plus";
import { VideoPlay, Refresh, Download } from "@element-plus/icons-vue";
import { ref } from "vue";
import type { AutoLog } from "@/types/autoLog/type";

import SockJS from "sockjs-client";
import Stomp from "stompjs";
import type { SunnyRunInfo } from "@/types/sunnyRunInfo/type";
import { getClientsListApi } from "@/api/sunnyrun";

let stompClient: Stomp.Client;

//按执行端区分存储日志信息，至少拥有服务端日志对象
interface Logger {
  runner: string;
  content: AutoLog[];
}

const loggerList = ref<Logger[]>([{ runner: "平台端", content: [] }]);
//服务端一定会有，默认选中服务端
const selectedLogger = ref("平台端");

const projectStore = useProjectStore();
onMounted(() => {
  projectStore.listProjects();
  //获取客户端列表
  listClients();
  subscribe();
});

function selectProject(sunnyProject: SunnyProject) {
  projectStore.selectedProject = sunnyProject;
}

function runProject() {
  runProjectApi(projectStore.selectedProject.id).then(() => {
    ElMessage.success("开始运行项目：" + projectStore.selectedProject.name);
  });
}
//选中的客户端列表对象
const selectedClients = ref<string[]>([]);
//所有客户端的列表
const clientList = ref<string[]>([]);

/**
 * 调用客户端执行
 */
function runOnClient() {
  //拼接客户端运行信息，包括项目id和选中的客户端列表
  let runInfo: SunnyRunInfo = {
    projectId: projectStore.selectedProject.id,
    clientsList: selectedClients.value,
  };
  distributeRunApi(runInfo).then(({ data }) => {
    ElMessage.success(data);
  });
}

/**获取客户端列表，同时添加客户端日志存储对象 */
function listClients() {
  getClientsListApi().then(({ data }) => {
    clientList.value = data;
    //重新获取客户端列表的时候重置客户端列表
    loggerList.value = [{ runner: "平台端", content: [] }];
    clientList.value.forEach((client) => {
      loggerList.value.push({ runner: client.split(":")[0], content: [] });
    });
  });
}

function subscribe() {
  //创建sockjs连接端点
  var socket = new SockJS("http://localhost:18080/sunnyWebSocket");
  //创建一个客户端
  stompClient = Stomp.over(socket);
  //完成连接
  stompClient.connect({}, function (frame) {
    console.log("Connected: " + frame);
    //进行订阅
    stompClient.subscribe(
      "/topic/allLog",
      //回调函数，对拿到的信息如何处理
      function (response) {
        console.log("完整的返回信息", response);
        //解析字符串为AutoLog对象
        let logContent = JSON.parse(response.body) as AutoLog;
        //遍历logger列表，如果日志的threadName中包含logger的执行端信息，那就存到对应的日志列表里
        loggerList.value.forEach((logger) => {
          //判断logger的名字是否在线程名中。
          if (logContent.threadName.indexOf(logger.runner) != -1) {
            logger.content.push(logContent);
          }
        });
      }
    );
  });
}

function downloadClient() {
  window.open("http://192.168.95.138:33333/sunny-client-win32-x64.zip");
}

function disconnect() {
  if (stompClient !== null) {
    stompClient.disconnect(() => {
      console.log("已断开连接");
    });
  }
  console.log("Disconnected");
}

onUnmounted(() => {
  disconnect();
});
</script>

<style scoped>
.project-wrapper {
  display: flex;
  justify-content: left;
  overflow-x: auto;
}

.project-wrapper > div {
  margin-right: 20px;
}

.project-wrapper > div:last-child {
  margin-right: 0;
}

.log-wrapper {
  background-color: black;
  border: 2px solid green;
  height: calc(100vh - 370px);
  color: white;
}

.selected-project {
  background-color: #a0cfff;
}

.INFO {
  color: #95d475;
}

.WARN {
  color: #eebe77;
}

.ERROR {
  color: #f89898;
}
</style>
